Write a custom CUDA kernel to optimize `Penalized Tanh` activation.

Formula: f(x) = tanh(x) if x > 0 else alpha * tanh(x)
This is equivalent to: tanh(x) * (x > 0 ? 1 : alpha)

Problem Analysis:
1. Memory Bandwidth: As an element-wise activation function, the arithmetic intensity is low. The performance is dominated by the speed of reading input and writing output (Memory Bound).
2. Tanh Cost: calculating `tanh` involves expensive exponential operations. However, modern GPUs have Special Function Units (SFUs), and the memory latency usually dominates.
3. Multiple Passes: A naive PyTorch implementation might compute `tanh(x)`, create a mask `x>0`, and then combine, resulting in redundant reads/writes.

Optimization Strategy: Fused Element-wise Kernel with Vectorization

1. One-Pass Fused Kernel: Perform the tanh computation and the conditional scaling in a single pass. Load `x`, compute `t = tanh(x)`, apply scaling based on the sign of `x`, and store.

2. Vectorized Loads (float4): Use `float4` to load 4 float elements (128 bits) per thread instruction. This is the most effective optimization for memory-bound kernels on Nvidia GPUs.

3. Instruction Optimization: Calculate `tanh(x)` once per element. The branching logic `x > 0` is cheap compared to memory access.

4. Kernel Configuration: Launch a 1D grid with enough blocks to cover the entire tensor size.
  
Here's an example to show you the syntax of inline embedding custom CUDA operators in torch: The example given architecture is:   
  
```python
import torch
import torch.nn as nn
import torch.nn.functional as F

BATCH_SIZE = 4096
HIDDEN_DIM = 4096
SHAPE = (BATCH_SIZE, HIDDEN_DIM)

ALPHA_VAL = 0.25

class PenalizedTanh(nn.Module):
    """
    Penalized Tanh
    https://arxiv.org/pdf/1602.05980
    f(x) = tanh(x)       if x > 0
           alpha * tanh(x) if x <= 0
    """
    def __init__(self, alpha=0.25):
        super(PenalizedTanh, self).__init__()
        self.alpha = alpha

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        t = torch.tanh(x)
        return torch.where(x > 0, t, self.alpha * t)

class Model(nn.Module):
    def __init__(self, alpha=0.25):
        super(Model, self).__init__()
        self.act = PenalizedTanh(alpha=alpha)
    
    def forward(self, x):
        return self.act(x)

def get_inputs():
    input_tensor = torch.randn(SHAPE, dtype=torch.float32)
    return [input_tensor.contiguous()]

def get_init_inputs():
    return [ALPHA_VAL]